/**
 * Copyright (C) 2013 DaiKit.com - daikit4gxt module (admin@daikit.com)
 *
 *         Project home : http://code.daikit.com/daikit4gxt
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.daikit.daikit4gxt.client.log;

import java.util.HashMap;
import java.util.Map;

import com.allen_sauer.gwt.log.client.Log;

/**
 * Logger to be used for client side logging.
 * 
 * @author tcaselli
 * @version $Revision$ Last modifier: $Author$ Last commit: $Date$
 */
public class DkLogger
{

	private final String pattern;

	private static final Map<String, DkLogger> INSTANCES = new HashMap<String, DkLogger>();

	private DkLogger(final Class<?> clazz)
	{
		final String clazzSimpleName = (clazz == null ? "null" : clazz.toString());
		this.pattern = "[" + clazzSimpleName.substring(clazzSimpleName.lastIndexOf(".") + 1) + "] ";
		INSTANCES.put(clazz.toString(), this);
	}

	/**
	 * Retrieve an instance of log for the given class.
	 * 
	 * @param clazz
	 *            the class to retrieve log of.
	 * @return an instance of {@link DkLogger}
	 */
	public static DkLogger getLog(final Class<?> clazz)
	{
		DkLogger instance = INSTANCES.get(clazz.getName());
		if (instance == null)
		{
			instance = new DkLogger(clazz);
			INSTANCES.put(clazz.getName(), instance);
		}
		return instance;
	}

	/**
	 * Log the given message in INFO level.
	 * 
	 * @param message
	 *            the message to be logged
	 */
	public void info(final Object message)
	{
		Log.info(pattern + message);
	}

	/**
	 * Log the given message in INFO level.
	 * 
	 * @param message
	 *            the message to be logged
	 * @param e
	 *            the error if any
	 */
	public void info(final Object message, final Throwable e)
	{
		Log.info(pattern + message, e);
	}

	/**
	 * Log the given message in DEBUG level.
	 * 
	 * @param message
	 *            the message to be logged
	 */
	public void debug(final Object message)
	{
		Log.debug(pattern + message);
	}

	/**
	 * Log the given message in DEBUG level.
	 * 
	 * @param message
	 *            the message to be logged
	 * @param e
	 *            the error if any
	 */
	public void debug(final Object message, final Throwable e)
	{
		Log.debug(pattern + message, e);
	}

	/**
	 * Log the given message in ERROR level.
	 * 
	 * @param message
	 *            the message to be logged
	 */
	public void error(final Object message)
	{
		Log.error(pattern + message);
	}

	/**
	 * Log the given message in ERROR level.
	 * 
	 * @param message
	 *            the message to be logged
	 * @param e
	 *            the error if any
	 */
	public void error(final Object message, final Throwable e)
	{
		Log.error(pattern + message, e);
	}

	/**
	 * Log the given message in WARN level.
	 * 
	 * @param message
	 *            the message to be logged
	 */
	public void warn(final Object message)
	{
		Log.warn(pattern + message);
	}

	/**
	 * Log the given message in WARN level.
	 * 
	 * @param message
	 *            the message to be logged
	 * @param e
	 *            the error if any
	 */
	public void warn(final Object message, final Throwable e)
	{
		Log.warn(pattern + message, e);
	}

	/**
	 * Log the given message in INFO level.
	 * 
	 * @param clazz
	 *            the Class to get logger from
	 * @param message
	 *            the message to be logged
	 */
	public static void info(final Class<?> clazz, final Object message)
	{
		getLog(clazz).info(message);
	}

	/**
	 * Log the given message in INFO level.
	 * 
	 * @param clazz
	 *            the Class to get logger from
	 * @param message
	 *            the message to be logged
	 * @param e
	 *            the error if any
	 */
	public static void info(final Class<?> clazz, final Object message, final Throwable e)
	{
		getLog(clazz).info(message, e);
	}

	/**
	 * Log the given message in DEBUG level.
	 * 
	 * @param clazz
	 *            the Class to get logger from
	 * @param message
	 *            the message to be logged
	 */
	public static void debug(final Class<?> clazz, final Object message)
	{
		getLog(clazz).debug(message);
	}

	/**
	 * Log the given message in DEBUG level.
	 * 
	 * @param clazz
	 *            the Class to get logger from
	 * @param message
	 *            the message to be logged
	 * @param e
	 *            the error if any
	 */
	public static void debug(final Class<?> clazz, final Object message, final Throwable e)
	{
		getLog(clazz).debug(message, e);
	}

	/**
	 * Log the given message in ERROR level.
	 * 
	 * @param clazz
	 *            the Class to get logger from
	 * @param message
	 *            the message to be logged
	 */
	public static void error(final Class<?> clazz, final Object message)
	{
		getLog(clazz).error(message);
	}

	/**
	 * Log the given message in ERROR level.
	 * 
	 * @param clazz
	 *            the Class to get logger from
	 * @param message
	 *            the message to be logged
	 * @param e
	 *            the error if any
	 */
	public static void error(final Class<?> clazz, final Object message, final Throwable e)
	{
		getLog(clazz).error(message, e);
	}

	/**
	 * Log the given message in WARN level.
	 * 
	 * @param clazz
	 *            the Class to get logger from
	 * @param message
	 *            the message to be logged
	 */
	public static void warn(final Class<?> clazz, final Object message)
	{
		getLog(clazz).warn(message);
	}

	/**
	 * Log the given message in WARN level.
	 * 
	 * @param clazz
	 *            the Class to get logger from
	 * @param message
	 *            the message to be logged
	 * @param e
	 *            the error if any
	 */
	public static void warn(final Class<?> clazz, final Object message, final Throwable e)
	{
		getLog(clazz).warn(message, e);
	}

	/**
	 * @return whether debug is enabled.
	 */
	public boolean isDebugEnabled()
	{
		return Log.isDebugEnabled();
	}

	/**
	 * @return whether info is enabled.
	 */
	public boolean isInfoEnabled()
	{
		return Log.isInfoEnabled();
	}

	/**
	 * @return whether warn is enabled.
	 */
	public boolean isWarnEnabled()
	{
		return Log.isWarnEnabled();
	}

	/**
	 * @return whether error is enabled.
	 */
	public boolean isErrorEnabled()
	{
		return Log.isErrorEnabled();
	}
}
